home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / winsock / ircii2-6.zip / SRC\IRCII-2.6\SOURCE\HELP.C < prev    next >
C/C++ Source or Header  |  1994-12-31  |  20KB  |  897 lines

  1. /*
  2.  * help.c: handles the help stuff for irc 
  3.  *
  4.  * Written by Michael Sandrof
  5.  * Extensively modified by Troy Rollo
  6.  * Re-modified by Matthew Green
  7.  *
  8.  * Copyright(c) 1992 
  9.  *
  10.  * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
  11.  */
  12.  
  13. /*
  14.  * This has been replaced almost entirely from the original by Michael
  15.  * Sandrof in order to fit in with the multiple screen code.
  16.  *
  17.  * ugh, this wasn't easy to do, but I got there, after working out what
  18.  * had been changed and why, by myself - phone, October 1992.
  19.  *
  20.  * And when I started getting /window create working, I discovered new
  21.  * bugs, and there has been a few more major changes in here again.
  22.  * It is illegal to call help from more than one screen, at the moment,
  23.  * because there is to much to keep track of - phone, jan 1993.
  24.  */
  25.  
  26. #ifndef lint
  27. static    char    rcsid[] = "@(#)$Id: help.c,v 1.25 1994/10/09 06:39:35 mrg Stab $";
  28. #endif
  29.  
  30. #include "irc.h"
  31.  
  32. /* stuff from gnu autoconf docs */
  33.  
  34. #ifdef NeXT        /* ugly hack 'cause configure don't grok it -phone */
  35. # define SYSDIR
  36. #endif
  37.  
  38. #if defined(DIRENT) || defined(_POSIX_SOURCE)
  39. # include <dirent.h>
  40. # define NLENGTH(d) (strlen((d)->d_name)
  41. #else /* DIRENT || _POSIX_SOURCE */
  42. # define dirent direct
  43. # define NLENGTH(d) ((d)->d_namlen)
  44. # ifdef SYSNDIR
  45. #  include <sys/ndir.h>
  46. # endif /* SYSNDIR */
  47. # ifdef SYSDIR
  48. #  include <sys/dir.h>
  49. # endif /* SYSDIR */
  50. # ifdef NDIR
  51. #  include <ndir.h>
  52. # endif /* NDIR */
  53. #endif /* DIRENT || _POSIX_VERSION */
  54.  
  55. #include <sys/stat.h>
  56.  
  57. #include "term.h"
  58. #include "server.h"
  59. #include "vars.h"
  60. #include "ircaux.h"
  61. #include "input.h"
  62. #include "window.h"
  63. #include "screen.h"
  64. #include "output.h"
  65.  
  66. #if defined(ISC22)
  67. extern char *strrchr();
  68. # define rindex strrchr
  69. # include <sys/dirent.h>
  70. # define direct dirent
  71. #endif /* ISC22 */
  72.  
  73. /* Forward declarations */
  74.  
  75. static    void    help_me __P((char *, char *));
  76. static    void    help_show_paused_topic __P((char *));
  77. static    void    create_help_window __P((void));
  78. static    void    set_help_screen __P((Screen *));
  79.  
  80. /*
  81.  * A few variables here - A lot added to get help working with
  82.  * non - recursive calls to irc_io, and also have it still 
  83.  * reading things from the server(s), so not to ping timeout.
  84.  */
  85. static    int    use_help_service = 0;
  86. static    Window    *help_window = (Window *) 0;
  87. static    FILE    *help_fp;
  88. static    char    no_help[] = "NOHELP";
  89. static    int    entry_size;
  90. static    char    *this_arg;
  91. static    int    finished_help_paging = 0;
  92. static    int    help_show_directory = 0;
  93. static    int    help_paused_lines;
  94. static    int    dont_pause_topic = 0;
  95. static    Screen  *help_screen = (Screen *) 0;
  96. static    char    *help_paused_topic[100];    /* 100 should be enough */
  97. static    char    paused_topic[128];
  98. static    char    FAR help_topic_list[BIG_BUFFER_SIZE + 1] = "";
  99. static    int    use_help_window = 0;
  100. static    char    *help_service;
  101.  
  102. /* we are piglet */
  103.  
  104. /* compar: used by scandir to alphabetize the help entries */
  105. static    int
  106. compar(e1, e2)
  107.     struct    dirent    **e1,
  108.             **e2;
  109. {
  110.     return (my_stricmp((*e1)->d_name, (*e2)->d_name));
  111. }
  112.  
  113. /*
  114.  * selectent: used by scandir to decide which entries to include in the help
  115.  * listing.  
  116.  */
  117. static    int
  118. selectent(entry)
  119.     struct    dirent    *entry;
  120. {
  121.     if (*(entry->d_name) == '.')
  122.         return (0);
  123.     if (my_strnicmp(entry->d_name, this_arg, strlen(this_arg)))
  124.         return (0);
  125.     else
  126.     {
  127.         int len = strlen(entry->d_name);
  128. #ifdef ZCAT
  129.         char *temp;
  130.     /*
  131.      * Handle major length of filename is case of suffix .Z:
  132.      * stripping suffix length
  133.      */
  134.         temp = &(entry->d_name[len - strlen(ZSUFFIX)]);
  135.         if (!strcmp(temp, ZSUFFIX))
  136.             len -= strlen(ZSUFFIX);
  137. #endif /*ZCAT*/
  138.         entry_size = (len > entry_size) ? len : entry_size;
  139.         return (1);
  140.     }
  141. }
  142.  
  143. /*
  144.  * show_help:  show's either a page of text from a help_fp, or the whole
  145.  * thing, depending on the value of HELP_PAGER_VAR.  If it gets to the end,
  146.  * (in either case it will eventally), it closes the file, and returns 0
  147.  * to indicate this.
  148.  */ 
  149. static    int
  150. show_help(window, name)
  151.     Window    *window;
  152.     char    *name;
  153. {
  154.     Window    *old_window;
  155.     int    rows = 0;
  156.     char    line[81];
  157.  
  158.     if (window)
  159.     {
  160.         old_window = curr_scr_win;
  161.         curr_scr_win = window;
  162.     }
  163.     else
  164.     {
  165.         old_window = (Window *) 0;
  166.         window = curr_scr_win;
  167.     }
  168.     if (get_int_var(HELP_PAGER_VAR))
  169.         rows = window->display_size;
  170.     while (--rows)
  171.     {
  172.          if (fgets(line, 80, help_fp))
  173.         {
  174.             if (*(line + strlen(line) - 1) == '\n')
  175.             *(line + strlen(line) - 1) = (char) 0;
  176.  
  177.     /*
  178.      * I want to remove the else portion of this code, as I
  179.      * find it offsensive, but too many help files rely on
  180.      * it.. sigh.. -phone
  181.      */
  182. #if NON_FASCIST_HELP
  183.             help_put_it(name, "%s", line);
  184. #else
  185.  
  186.             switch (*line)
  187.             {
  188.             case '*':
  189.                 if (get_server_operator(from_server))
  190.                     help_put_it(name, "%s", line + 1);
  191.                 break;
  192.             case '-':
  193.                 if (!get_server_operator(from_server))
  194.                     help_put_it(name, "%s", line + 1);
  195.                 break;
  196.             default:
  197.                 help_put_it(name, "%s", line);
  198.                 break;
  199.             }
  200. #endif
  201.         }
  202.         else
  203.         {
  204.             fclose(help_fp);
  205.             return (0);
  206.         }
  207.     }
  208.     return (1);
  209. }
  210.  
  211. /*
  212.  * help_prompt: The main procedure called to display the help file
  213.  * currently being accessed.  Using add_wait_prompt(), it sets it
  214.  * self up to be recalled when the next page is asked for.   If
  215.  * called when we have finished paging the help file, we exit, as
  216.  * there is nothing left to show.  If line is 'q' or 'Q', exit the
  217.  * help pager, clean up, etc..  If all is cool for now, we call
  218.  * show_help, and either if its finished, exit, or prompt for the
  219.  * next page.   From here, if we've finished the help page, and
  220.  * doing help prompts, prompt for the help..
  221.  */
  222.  
  223. static    void
  224. help_prompt(name, line)
  225.     char    *name,
  226.         *line;
  227. {
  228.     if (finished_help_paging)
  229.     {
  230.         if (*paused_topic)
  231.             help_show_paused_topic(paused_topic);
  232.         return;
  233.     }
  234.  
  235.     if (line && ((*line == 'q') || (*line == 'Q')))
  236.     {
  237.         finished_help_paging = 1;
  238.         fclose(help_fp);
  239.         set_help_screen((Screen *) 0);
  240.         return;
  241.     }
  242.  
  243.     if (show_help(help_window, name))
  244.         add_wait_prompt("*** Hit any key for more, 'q' to quit ***",
  245.             help_prompt, name, WAIT_PROMPT_KEY);
  246.     else
  247.     {
  248.         finished_help_paging = 1;
  249.         fclose(help_fp);
  250.         if (help_show_directory)
  251.         {
  252.             if (get_int_var(HELP_PAGER_VAR))
  253.                 add_wait_prompt("*** Hit any key to end ***", 
  254.                     help_show_paused_topic, paused_topic,
  255.                     WAIT_PROMPT_KEY);
  256.             else
  257.             {
  258.                 help_show_paused_topic(paused_topic);
  259.                 set_help_screen((Screen *) 0);
  260.             }
  261.             help_show_directory = 0;
  262.             return;
  263.         }
  264.     }
  265.  
  266.     if (finished_help_paging)
  267.     {
  268.         if (get_int_var(HELP_PROMPT_VAR))
  269.         {
  270.             define_big_buffer(tmp);
  271.  
  272.             sprintf(tmp, "%s%sHelp? ", help_topic_list,
  273.                 *help_topic_list ? " " : "");
  274.             add_wait_prompt(tmp, help_me, help_topic_list,
  275.                 WAIT_PROMPT_LINE);
  276.             free_big_buffer(tmp);
  277.         }
  278.         else
  279.         {
  280.             if (*paused_topic)
  281.                 help_show_paused_topic(paused_topic);
  282.             set_help_screen((Screen *) 0);
  283.         }
  284.     }
  285. }
  286.  
  287. /*
  288.  * help_topic:  Given a topic, we search the help directory, and try to
  289.  * find the right file, if all is cool, and we can open it, or zcat it,
  290.  * then we call help_prompt to get the actually displaying of the file
  291.  * on the road.
  292.  */
  293. static    void
  294. help_topic(path, name)
  295.     char    *path;
  296.     char    *name;
  297. {
  298.     struct    stat    stat_buf;
  299.     define_big_buffer(filename);
  300.  
  301. #ifdef ZCAT
  302.     char    *name_z = (char *) 0;
  303.     char    *temp;
  304. #endif /* ZCAT */
  305.  
  306.     if (name == (char *) 0)
  307.     {
  308.         free_big_buffer(filename);
  309.         return;
  310.     }
  311.  
  312.     /*
  313.      * Check the existence of <name> or <name>.Z .. Handle suffix
  314.      * .Z if present.  Open the file if it isn't present, zcat the
  315.      * file if it is present, and ends with .Z ..
  316.      */
  317.  
  318.     sprintf(filename, "%s/%s", path, name);
  319.  
  320. #ifdef ZCAT
  321.  
  322.     if (strcmp(name + (strlen(name) - strlen(ZSUFFIX)), ZSUFFIX))
  323.     {
  324.         malloc_strcpy(&name_z, name);
  325.         malloc_strcat(&name_z, ZSUFFIX);
  326.     }
  327.     if (stat_file(filename, &stat_buf) == -1)
  328.     {
  329.         sprintf(filename, "%s/%s", path, name_z);
  330.         if (stat_file(filename, &stat_buf) == -1)
  331.         {
  332.             help_put_it(name, "*** No help available on %s: Use \
  333. ? for list of topics", name);
  334.             return;
  335.         }
  336.         else
  337.             name = name_z;
  338.     }
  339.     else
  340.         new_free(&name_z);
  341. #else
  342.     stat_file(filename, &stat_buf);
  343.  
  344. #endif /* ZCAT */
  345.  
  346.     if (stat_buf.st_mode & S_IFDIR)
  347.     {
  348.         free_big_buffer(filename);
  349.         return;
  350.     }
  351.  
  352. #ifdef ZCAT
  353.  
  354.     if (strcmp(filename + (strlen(filename) - strlen(ZSUFFIX)), ZSUFFIX))
  355.     {
  356.  
  357. #endif /* ZCAT */
  358.  
  359.         if ((help_fp = fopen(filename, "r")) == (FILE *) 0)
  360.         {
  361.             help_put_it(name, "*** No help available on %s: Use \
  362. ? for list of topics", name);
  363.             free_big_buffer(filename);
  364.             return;
  365.         }
  366. #ifdef ZCAT
  367.  
  368.     }
  369.     else
  370.     {
  371.         if ((help_fp = zcat(filename)) == (FILE *) 0)
  372.         {
  373.             help_put_it(name, "*** No help available on %s: Use \
  374. ? for list of topics", name);
  375.             free_big_buffer(filename);
  376.             return;
  377.         }
  378.     }
  379.  
  380.     /*
  381.      * If the name ended in a .Z, truncate it, so we display the name
  382.      * with out the .Z
  383.      */
  384.  
  385.     temp = &(name[strlen(name) - strlen(ZSUFFIX)]);
  386.     if (!strcmp(temp, ZSUFFIX))
  387.         temp[0] = '\0';
  388.     
  389. #endif /* ZCAT */
  390.  
  391.     /*
  392.      * Hopefully now we have got a file descriptor <help_fp>, a name
  393.      * so we start displaying the help file, calling help_prompt for
  394.      * the first time.
  395.      */
  396.  
  397.     help_put_it(name, "*** Help on %s", name);
  398.     help_prompt(name, (char *) 0);
  399.     free_big_buffer(filename);
  400. }
  401.  
  402. /*
  403.  * help_pause_add_line: this procedure does a help_put_it() call, but
  404.  * puts off the calling, until help_show_paused_topic() is called.
  405.  * I do this because I need to create the list of help topics, but
  406.  * not show them, until we've seen the whole file, so we called
  407.  * help_show_paused_topic() when we've seen the file, if it is needed.
  408.  */
  409.  
  410. /*VARARGS*/
  411. static    void
  412. #ifdef USE_STDARG_H
  413. help_pause_add_line(char *format, ...)
  414. {
  415.     va_list vl;
  416. #else
  417. help_pause_add_line(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10)
  418.     char    *format;
  419.     char    *arg1,
  420.         *arg2,
  421.         *arg3,
  422.         *arg4,
  423.         *arg5,
  424.         *arg6,
  425.         *arg7,
  426.         *arg8,
  427.         *arg9,
  428.         *arg10;
  429. {
  430. #endif
  431.  
  432.     define_big_buffer(buf);
  433.  
  434. #ifdef USE_STDARG_H
  435.     va_start(vl, format);
  436.     vsprintf(buf, format, vl);
  437.     va_end(vl);
  438. #else
  439.     sprintf(buf, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
  440.             arg8, arg9, arg10);
  441. #endif
  442.     malloc_strcpy(&help_paused_topic[help_paused_lines], buf);
  443.     help_paused_lines++;
  444.     free_big_buffer(buf);
  445. }
  446.  
  447. /*
  448.  * help_show_paused_topic:  see above.  Called when we've seen the
  449.  * whole help file, and we have a list of topics to display.
  450.  */
  451. static    void
  452. help_show_paused_topic(name)
  453.     char    *name;
  454. {
  455.     int    i = 0;
  456.  
  457.     if (!help_paused_lines)
  458.         return;
  459.     for (i = 0; i < help_paused_lines; i++)
  460.     {
  461.         help_put_it(name, "%s", help_paused_topic[i]);
  462.         new_free(&help_paused_topic[i]);
  463.     }
  464.     if (get_int_var(HELP_PROMPT_VAR))
  465.     {
  466.         define_big_buffer(buf);
  467.  
  468.         sprintf(buf, "%s%sHelp? ", name, (name && *name) ? " " : "");
  469.         add_wait_prompt(buf, help_me, name, WAIT_PROMPT_LINE);
  470.         free_big_buffer(buf);
  471.     }
  472.     else
  473.         set_help_screen((Screen *) 0);
  474.  
  475.     dont_pause_topic = 0;
  476.     help_paused_lines = 0;
  477. }
  478.  
  479. /*
  480.  * help_me:  The big one.  The help procedure that handles working out
  481.  * what was actually requested, sets up the paused topic list if it is
  482.  * needed, does pretty much all the hard work.
  483.  */
  484. static    void
  485. help_me(topics, args)
  486.     char    *topics;
  487.     char    *args;
  488. {
  489.     char    *ptr;
  490.     struct    dirent    **namelist = NULL;
  491.     int    entries,
  492.         free_cnt = 0,
  493.         cnt,
  494.         i,
  495.         cols;
  496.     struct    stat    stat_buf;
  497.     define_big_buffer(path);
  498.     int    help_paused_first_call = 0;
  499.     char    *help_paused_path = (char *) 0;
  500.     char    *help_paused_name = (char *) 0;
  501.     char    *temp;
  502.     define_big_buffer(tmp);
  503.  
  504. #ifdef ZCAT
  505.     char    *arg_z = (char *) 0;
  506. #endif /*ZCAT*/ 
  507.  
  508.     strcpy(help_topic_list, topics);
  509.  
  510. #ifdef DAEMON_UID
  511.     if (DAEMON_UID == getuid())
  512.         ptr = DEFAULT_HELP_PATH;
  513.     else
  514. #endif
  515.         ptr = get_string_var(HELP_PATH_VAR);
  516.  
  517.     sprintf(path, "%s/%s", ptr, topics);
  518.     for (ptr = path; (ptr = index(ptr, ' '));)
  519.         *ptr = '/';
  520.  
  521.     /*
  522.      * first we check access to the help dir, whinge if we can't, then
  523.      * work out we need to ask them for more help, else we check the
  524.      * args list, and do the stuff 
  525.      */
  526.  
  527.     if (help_show_directory)
  528.     {
  529.         help_show_paused_topic(paused_topic);
  530.         help_show_directory = 0;
  531.     }
  532.         
  533.     finished_help_paging = 0;
  534.     if (access(path, R_OK|X_OK))
  535.     {
  536.         help_put_it(no_help, "*** Cannot access help directory!");
  537.         set_help_screen((Screen *) 0);
  538.         free_big_buffer(path);
  539.         free_big_buffer(tmp);
  540.         return;
  541.     }
  542.  
  543.     this_arg = next_arg(args, &args);
  544.     if (!this_arg && *help_topic_list && get_int_var(HELP_PROMPT_VAR))
  545.     {
  546.         if ((temp = rindex(help_topic_list, ' ')) != NULL)
  547.             *temp = '\0';
  548.         else
  549.             *help_topic_list = '\0';
  550.         sprintf(tmp, "%s%sHelp? ", help_topic_list,
  551.             *help_topic_list ? " " : "");
  552.         add_wait_prompt(tmp, help_me, help_topic_list,
  553.             WAIT_PROMPT_LINE);
  554.         free_big_buffer(path);
  555.         free_big_buffer(tmp);
  556.         return;
  557.     }
  558.  
  559.     if (!this_arg)        /*  && *help_topic_list) */
  560.     {
  561.         set_help_screen((Screen *) 0);
  562.         free_big_buffer(path);
  563.         free_big_buffer(tmp);
  564.         return;
  565.     }
  566.  
  567.     create_help_window();
  568.     while (this_arg)
  569.     {
  570.         message_from((char *) 0, LOG_CURRENT);
  571.         if (*this_arg == (char) 0)
  572.             help_topic(path, NULL);
  573.         if (strcmp(this_arg, "?") == 0)
  574.         {
  575.             this_arg = empty_string;
  576.             if (!dont_pause_topic)
  577.                 dont_pause_topic = 1;
  578.         }
  579.         entry_size = 0;
  580.  
  581.         /*
  582.          * here we clean the namelist if it exists, and then go to
  583.          * work on the directory.. working out if is dead, or if we
  584.          * can show some help, or create the paused topic list.
  585.          */
  586.  
  587.         if (namelist)
  588.         {
  589.             for (i = 0; i < free_cnt; i++)
  590.                 new_free(&(namelist[i]));
  591.             new_free(&namelist);
  592.         }
  593.         free_cnt = entries = scandir(path, &namelist, selectent,
  594.                 compar);
  595.         /* special case to handle stuff like LOG and LOGFILE */
  596.         if (entries > 1)
  597.         {
  598. #ifdef ZCAT
  599.         /* Check if exist compressed or uncompressed entries */
  600.             malloc_strcpy(&arg_z, this_arg);
  601.             malloc_strcat(&arg_z, ZSUFFIX);
  602.             if (my_stricmp(namelist[0]->d_name, arg_z) == 0 ||
  603.                 my_stricmp(namelist[0]->d_name, this_arg) == 0)
  604. #else
  605.             if (my_stricmp(namelist[0]->d_name, this_arg) == 0)
  606. #endif /*ZCAT*/
  607.                 entries = 1;
  608. #ifdef ZCAT
  609.             new_free(&arg_z);
  610. #endif /*ZCAT*/
  611.         }
  612.  
  613.         /*
  614.          * entries: -1 means something really died, 0 means there
  615.          * was no help, 1, means it wasn't a directory, and so to
  616.          * show the help file, and the default means to add the
  617.          * stuff to the paused topic list..
  618.          */
  619.  
  620.         if (!*help_topic_list)
  621.             dont_pause_topic = 1;
  622.         switch (entries)
  623.         {
  624.         case -1:
  625.             help_put_it(no_help, "*** Error during help function: %s", strerror(errno));
  626.             set_help_screen((Screen *) 0);
  627.             if (help_paused_first_call)
  628.             {
  629.                 help_topic(help_paused_path, help_paused_name);
  630.                 help_paused_first_call = 0;
  631.                 new_free(&help_paused_path);
  632.                 new_free(&help_paused_name);
  633.             }
  634.             free_big_buffer(path);
  635.             free_big_buffer(tmp);
  636.             return;
  637.         case 0:
  638.             help_put_it(this_arg, "*** No help available on %s: Use ? for list of topics", this_arg);
  639.             if (!get_int_var(HELP_PROMPT_VAR))
  640.             {
  641.                 set_help_screen((Screen *) 0);
  642.                 break;
  643.             }
  644.             sprintf(tmp, "%s%sHelp? ", help_topic_list,
  645.                 *help_topic_list ? " " : "");
  646.             add_wait_prompt(tmp, help_me, help_topic_list,
  647.                     WAIT_PROMPT_LINE);
  648.             if (help_paused_first_call)
  649.             {
  650.                 help_topic(help_paused_path, help_paused_name);
  651.                 help_paused_first_call = 0;
  652.                 new_free(&help_paused_path);
  653.                 new_free(&help_paused_name);
  654.             }
  655.             for (i = 0; i < free_cnt; i++)
  656.             {
  657.                 new_free(&namelist[i]);
  658.             }
  659.             break;
  660.         case 1:
  661.             sprintf(tmp, "%s/%s", path, namelist[0]->d_name);
  662.             stat_file(tmp, &stat_buf);
  663.             if (stat_buf.st_mode & S_IFDIR)
  664.             {
  665.                 strcpy(path, tmp);
  666.                 if (*help_topic_list)
  667.                     strcat(help_topic_list, " ");
  668.                 strcat(help_topic_list, namelist[0]->d_name);
  669.                 if ((this_arg = next_arg(args, &args)) ==
  670.                         (char *) 0)
  671.                 {
  672.                     help_paused_first_call = 1;
  673.                     malloc_strcpy(&help_paused_path, path);
  674.                     malloc_strcpy(&help_paused_name,
  675.                         namelist[0]->d_name);
  676.                     dont_pause_topic = -1;
  677.                     this_arg = "?";
  678.                 }
  679.                 for (i = 0; i < free_cnt; i++)
  680.                 {
  681.                     new_free(&namelist[i]);
  682.                 }
  683.                 continue;
  684.             }
  685.             else
  686.             {
  687.                 help_topic(path, namelist[0]->d_name);
  688.                 finished_help_paging = 0;    /* this is a big kludge */
  689.                 for (i = 0; i < free_cnt; i++)
  690.                 {
  691.                     new_free(&namelist[i]);
  692.                 }
  693.                 break;
  694.             }
  695.         default:
  696.             help_show_directory = 1;
  697.             strcpy(paused_topic, help_topic_list);
  698.             help_pause_add_line("*** %s choices:", help_topic_list);
  699.             *buffer = (char) 0;
  700.             cnt = 0;
  701.             entry_size += 2;
  702.             cols = (CO - 10) / entry_size;
  703.             for (i = 0; i < entries; i++)
  704.             {
  705. #ifdef ZCAT
  706.         /*
  707.          * In tmp store the actual help choice and strip .Z
  708.          * suffix in compressed files: put filename (without
  709.          * .Z) on the help screen.  If it is the first choice
  710.          * cat it to the buffer and save the last choice
  711.          */
  712.                 strmcpy(tmp, namelist[i]->d_name, BIG_BUFFER_SIZE);
  713.                 temp = &(tmp[strlen(tmp) - strlen(ZSUFFIX)]);
  714.                 if (!strcmp(temp, ZSUFFIX))
  715.                     temp[0] = '\0';
  716.                 strmcat(buffer, tmp, BIG_BUFFER_SIZE);
  717. #else
  718.                 strmcat(buffer, namelist[i]->d_name, BIG_BUFFER_SIZE);
  719. #endif /*ZCAT*/
  720.                 if (++cnt == cols)
  721.                 {
  722.                     help_pause_add_line("%s", buffer);
  723.                     *buffer = (char) 0;
  724.                     cnt = 0;
  725.                 }
  726.                 else
  727.                 {
  728.                     int    x,
  729.                         l;
  730.  
  731.                     l = strlen(namelist[i]->d_name);
  732. #ifdef ZCAT
  733.                     /* XXX - this needs to be fixed properly */
  734.                     if ((temp = rindex(namelist[i]->d_name, '.')) != NULL &&
  735.                         index(namelist[i]->d_name, *ZSUFFIX))
  736.                     l -= strlen(ZSUFFIX);
  737. #endif /*ZCAT*/
  738.                     for (x = l; x < entry_size; x++)
  739.                         strmcat(buffer, " ", BIG_BUFFER_SIZE);
  740.                 }
  741.             }
  742.             help_pause_add_line("%s", buffer);
  743.             if (help_paused_first_call)
  744.             {
  745.                 help_topic(help_paused_path, help_paused_name);
  746.                 help_paused_first_call = 0;
  747.                 new_free(&help_paused_path);
  748.                 new_free(&help_paused_name);
  749.             }
  750.             if (dont_pause_topic == 1)
  751.             {
  752.                 help_show_paused_topic(paused_topic);
  753.                 help_show_directory = 0;
  754.             }
  755.             break;
  756.         }
  757.         for (i = 0; i < free_cnt; i++)
  758.         {
  759.             new_free(&namelist[i]);
  760.         }
  761.         new_free(&namelist);
  762.         break;
  763.     }
  764.     /*
  765.      * This one is for when there was never a topic and the prompt
  766.      * never got a topic..  and help_screen was never reset..
  767.      * phone, jan 1993.
  768.      */
  769.     if (!*help_topic_list && finished_help_paging)
  770.         set_help_screen((Screen *) 0);
  771.     free_big_buffer(path);
  772.     free_big_buffer(tmp);
  773. }
  774.  
  775. /*
  776.  * help: the HELP command, gives help listings for any and all topics out
  777.  * there 
  778.  */
  779. /*ARGSUSED*/
  780. void
  781. help(command, args)
  782.     char    *command,
  783.         *args;
  784. {
  785.     char    *help_path;
  786.  
  787.     finished_help_paging = 0;
  788.     help_show_directory = 0;
  789.     dont_pause_topic = 0;
  790.     use_help_window = 0;
  791.  
  792.     /*
  793.      * The idea here is to work out what sort of help we are using - 
  794.      * either the installed help files, or some help service, what
  795.      * ever it maybe.  Once we have worked this out, if we are using
  796.      * a help window, set it up properly.
  797.      */
  798.  
  799. #ifdef DAEMON_UID
  800.     if (DAEMON_UID == getuid())
  801.         help_path = DEFAULT_HELP_PATH;
  802.     else
  803. #endif
  804.         help_path = get_string_var(HELP_PATH_VAR);
  805.     if (!(help_path && *help_path && !access(help_path, R_OK | X_OK)))
  806.     {
  807.         help_service = get_string_var(HELP_SERVICE_VAR);
  808.         if (!help_service || !*help_service)
  809.         {
  810.             help_put_it(no_help, "*** No HELP_PATH or HELP_SERVICE variable set");
  811.             return;
  812.         }
  813.         help_path = NULL;
  814.         use_help_service = 1;
  815.     }
  816.  
  817.     /*
  818.      * Here, if we are using the help files locally, we must ensure that
  819.      * we aren't doing HELP in a more than one screen - phone, jan 1993.
  820.      */
  821.  
  822.     if (help_path && help_screen && help_screen != current_screen)
  823.     {
  824.         say("You may not run help in two screens");
  825.         return;
  826.     }
  827.     help_screen = current_screen;
  828. #ifdef PHONE
  829.     if (help_window)
  830.         yell("--- something is fucked.  help_window is set!!");
  831. #endif
  832.     help_window = (Window *) 0;
  833.     if (use_help_service)
  834.     {
  835.         set_help_screen((Screen *) 0);
  836.         create_help_window();
  837.         send_to_server("PRIVMSG %s :%s",
  838.                 get_string_var(HELP_SERVICE_VAR),
  839.                 (args && *args) ? args : "?");
  840.     }
  841.     else
  842.         help_me(empty_string, (args && *args) ? args : "?");
  843.  
  844.     /*
  845.      * This section of code must be put somewhere so it is excuted when 
  846.      * _all_ help stuff is finished..  - phone
  847.      */
  848.  
  849. }
  850.  
  851. static    void
  852. create_help_window()
  853. {
  854.     if (help_window)
  855.         return;
  856.  
  857.     if (!dumb && get_int_var(HELP_WINDOW_VAR))
  858.     {
  859.         use_help_window = 1;
  860.         help_window = new_window();
  861.  
  862.         if (use_help_service)
  863.         {
  864.             query("QUERY", help_service);
  865.             if (get_int_var(HELP_PAGER_VAR))
  866.                 help_window->hold_mode = ON;
  867.             else
  868.                 help_window->hold_mode = OFF;
  869.         }
  870.         else
  871.             help_window->hold_mode = OFF;
  872.         update_all_windows();
  873.     }
  874.     else
  875.         help_window = curr_scr_win;
  876. }
  877.  
  878. static    void
  879. set_help_screen(screen)
  880.     Screen    *screen;
  881. {
  882.     help_screen = screen;
  883.     if (!help_screen && help_window)
  884.     {
  885.         if (use_help_window)
  886.         {
  887.             int display = window_display;
  888.  
  889.             window_display = 0;
  890.             delete_window(help_window);
  891.             window_display = display;
  892.         }
  893.         help_window = (Window *) 0;
  894.         update_all_windows();
  895.     }
  896. }
  897.